﻿/* 2012/10/2 */
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;

namespace Cosmos.Windows.Forms
{
    public partial class SplitTabArea : UserControl
    {
        /// <summary>
        /// Contains a collection of TabPage objects. 
        /// </summary>
        public class TabPageCollection : IEnumerable, ICollection, IList
        {
            private object _syncRoot;
            private SplitTabArea _owner;
            private List<TabPage> _tabPages;

            public TabPageCollection(SplitTabArea owner)
            {
                _syncRoot = new object();
                _owner = owner;
                _tabPages = new List<TabPage>();
            }

            public int IndexOf(TabPage page)
            {
                return _tabPages.IndexOf(page);
            }

            public bool Contains(TabPage page)
            {
                return _tabPages.Contains(page);
            }

            public void Clear()
            {
                lock (_syncRoot)
                {
                    _tabPages.Clear();
                    _owner.ClearTabPages();
                }
            }

            public int Add(TabPage page)
            {
                if (Contains(page))
                    return -1;

                lock (_syncRoot)
                {
                    _tabPages.Add(page);
                    _owner.AddTabPage(page);
                }

                return _tabPages.Count - 1;
            }

            public void Insert(int index, TabPage page)
            {
                if (Contains(page))
                    return;

                lock (_syncRoot)
                {
                    _owner.AddTabPage(page);
                    _tabPages.Insert(index, page);
                }
            }

            public void Remove(TabPage page)
            {
                if (!Contains(page))
                    return;

                lock (_syncRoot)
                {
                    _owner.RemoveTabPage(page);
                    _tabPages.Remove(page);
                }
            }

            public void RemoveAt(int index)
            {
                if (index >= 0 && index < _tabPages.Count)
                {
                    lock (_syncRoot)
                    {
                        _owner.RemoveTabPage(_tabPages[index]);
                        _tabPages.RemoveAt(index);
                    }
                }
            }

            public IEnumerator GetEnumerator()
            {
                lock (_syncRoot)
                {
                    foreach (TabPage aTabPage in _tabPages)
                    {
                        yield return aTabPage;
                    }
                }
            }

            public void CopyTo(Array array, int index)
            {
                if (array == null)
                    throw new ArgumentNullException();

                if (index < 0)
                    throw new ArgumentOutOfRangeException();

                if (array.Rank > 1 || index >= array.Length || Count > (array.Length - index))
                    throw new ArgumentException();

                lock (_syncRoot)
                {
                    for (int i = 0, j = index; i < Count && j < array.Length; i++, j++)
                    {
                        array.SetValue(_tabPages[i], j);
                    }
                }
            }

            int IList.IndexOf(object value)
            {
                if (value is TabPage)
                {
                    return IndexOf((TabPage)value);
                }
                else
                {
                    return -1;
                }
            }

            bool IList.Contains(object value)
            {
                if (value is TabPage)
                {
                    return Contains((TabPage)value);
                }
                else
                {
                    return false;
                }
            }

            int IList.Add(object value)
            {
                if (value is TabPage)
                {
                    return Add((TabPage)value);
                }
                else
                {
                    return -1;
                }
            }

            void IList.Insert(int index, object value)
            {
                if (value is TabPage)
                {
                    Insert(index, (TabPage)value);
                }                
            }

            void IList.Remove(object value)
            {
                if (value is TabPage)
                {
                    Remove((TabPage)value);
                }
            }

            void IList.RemoveAt(int index)
            {
                RemoveAt(index);
            }

            public bool IsSynchronized
            {
                get
                {
                    return true;
                }
            }

            public object SyncRoot
            {
                get
                {
                    return _syncRoot;
                }
            }

            public int Count
            {
                get
                {
                    return _tabPages.Count;
                }
            }

            bool IList.IsFixedSize
            {
                get
                {
                    return false;
                }
            }

            bool IList.IsReadOnly
            {
                get
                {
                    return false;
                }
            }

            public TabPage this[int index]
            {
                get
                {
                    return _tabPages[index];
                }

                set
                {
                    _tabPages[index] = value;
                }
            }

            object IList.this[int index]
            {
                get
                {
                    if (index < 0 || index > Count)
                        throw new ArgumentOutOfRangeException();

                    return (object)_tabPages[index];
                }

                set
                {
                    if (index < 0 || index > Count)
                        throw new ArgumentOutOfRangeException();

                    if (((IList)this).IsReadOnly)
                        throw new NotSupportedException();

                    if (!(value is TabPage))
                        throw new ArgumentException();

                    _tabPages[index] = (TabPage)value;
                }
            }
        }

        private TabPageCollection _tabPages;

        public SplitTabArea()
        {
            InitializeComponent();

            _tabPages = new TabPageCollection(this);

            SplitTabControl tabControl = new SplitTabControl();
            Controls.Add(tabControl);
            tabControl.Dock = DockStyle.Fill;
        }

        private void ClearTabPages()
        {
            if (Controls[0] is SplitTabControl)
            {
                SplitTabControl tabControl = (SplitTabControl)Controls[0];
                tabControl.TabPages.Clear();
            }
        }

        private void AddTabPage(TabPage page)
        {
            if (Controls[0] is SplitTabControl)
            {
                SplitTabControl tabControl = (SplitTabControl)Controls[0];
                tabControl.TabPages.Add(page);
            }
        }

        private void RemoveTabPage(TabPage page)
        {
            if (Controls[0] is SplitTabControl)
            {
                SplitTabControl tabControl = (SplitTabControl)Controls[0];
                tabControl.TabPages.Remove(page);
            }
        }

        /// <summary>
        /// Gets the collection of tab pages in this split tab area. 
        /// </summary>
        public TabPageCollection TabPages
        {
            get
            {
                return _tabPages;
            }
        }
    }
}
